﻿namespace Algoritmia.Schemes
{
   
    public interface IDecreaseAndConquerProblem<TSolution>
    {
        bool IsSimple { get; }
        TSolution TrivialSolution();
        IDecreaseAndConquerProblem<TSolution> Decrease();
        TSolution Process(TSolution solution);
    }

    public class DecreaseAndConquerSolver<TSolution>
    {
        public TSolution Solve(IDecreaseAndConquerProblem<TSolution> problem)
        {
            if (problem.IsSimple)
            {
                return problem.TrivialSolution();
            }
            else
            {
                return problem.Process(Solve(problem.Decrease()));
            }
        }
    }

    public class TailRecursiveDecreaseAndConquerSolver<TSolution>
    {
        public TSolution Solve(IDecreaseAndConquerProblem<TSolution> problem)
        {
            if (problem.IsSimple)
            {
                return problem.TrivialSolution();
            }
            else
            {
                return Solve(problem.Decrease());
            }
        }
    }

    public class IterativeDecreaseAndConquerSolver<TSolution>
    {
        public TSolution Solve(IDecreaseAndConquerProblem<TSolution> problem)
        {
            while (!problem.IsSimple)
            {
                problem = problem.Decrease();
            }
            return problem.TrivialSolution();
        }
    }

}
